package pl.interop.db.tests;

import java.io.File;
import java.sql.ResultSet;
import java.util.Map;
import java.util.logging.Logger;
import pl.interop.db.ResultSetTransformOutputEnum;
import pl.interop.db.SimpleAdoDB;
import pl.interop.db.exceptions.DBQueryException;
import pl.interop.logging.SimpleLogger;

/**
 * Test połączenia z bazą sqlite
 * wymaga sterownika JDBC dostępnego
 * z http://www.xerial.org/maven/repository/artifact/org/xerial/sqlite-jdbc/3.7.2/
 *
 * użyta wersja sterownika JDBC SQLite -> 3.7.2,
 * bez odwołań do kodu natywnego
 *
 * @author Karol Piątek
 */
public class SQLiteTest {

	static String MESSAGES_SEPARATOR = "\n\n**************\n";
	
	public static void main(String[] args) {

		SimpleLogger logger = SimpleLogger.getInstance(
									Logger.getLogger(SQLiteTest.class.getName())
								);

		try {



			//używamy tylko sterownika typu JDBC4 -
			//napisanego wyłącznie w Javie, bez odwołań do kodu natywnego
			System.setProperty("sqlite.purejava", "true");

			//pobranie instancji klasy SimpleAdoDB
			SimpleAdoDB adoDb = SimpleAdoDB.getInstance();


			//inicjalizacja sterownika
			String dbDriverName = "org.sqlite.JDBC";
			adoDb.initDbDriver(dbDriverName);

			//utworzenie bazy na dysku twardym
			//String databaseAccessURL = "jdbc:sqlite::memory:";
			File databaseFile = new File("testDb.db");

			//usunięcie pliku z bazą testową
			if(databaseFile.exists()){
				databaseFile.delete();
			}


			// ustanowienie połączenia z bazą danych
			final String databaseType = "jdbc:sqlite:";
			String databaseAccessURL = databaseType + databaseFile.getAbsolutePath();
			logger.echoDev("URL połączenia z bazą danych " + databaseAccessURL);


			Boolean connect = adoDb.connect(databaseAccessURL, "", "");
			logger.echoDev("Połączenie z bazą ustanowione " + connect);

			//utworzenie tabeli appAccounts
			Integer updateOrInsertResult = adoDb.ExecUpdate("drop table if exists appAccounts");
			updateOrInsertResult = adoDb.ExecUpdate("create table appAccounts (id integer, accountName string)");

			//dodanie informacji do tabeli
			String accountsModyfingStatement = "INSERT INTO appAccounts (id, accountName) VALUES(?,?)";
			updateOrInsertResult = adoDb.ExecUpdate(accountsModyfingStatement,1,"Handlowiec");
			updateOrInsertResult = adoDb.ExecUpdate(accountsModyfingStatement,2,"Wdrożeniowiec");
			updateOrInsertResult = adoDb.ExecUpdate(accountsModyfingStatement,3,"Tester");
			updateOrInsertResult = adoDb.ExecUpdate(accountsModyfingStatement,4,"Programista");

			//pobranie informacji z tabeli
			ResultSet allAppAccounts = adoDb.ExecSelect("SELECT * FROM appAccounts");


			//formatowanie i pobranie jednego wiersza z zapytania
			Map transformResultSet = adoDb.fetch(allAppAccounts, ResultSetTransformOutputEnum.FETCH_ROW);
			StringBuilder messageBuilder = new StringBuilder();

			messageBuilder.append(MESSAGES_SEPARATOR);
			messageBuilder.append("Jeden wiersz \n");
			messageBuilder.append(transformResultSet.toString());
			logger.echoDev(messageBuilder.toString());

			//usunięcie danych tekstowych
			messageBuilder.delete(0, messageBuilder.length() - 1);

			//pobranie na nowo wierszy z tego samego zapytania
			//z możliwością przerwania po 3 wierszu
			
			messageBuilder.append(MESSAGES_SEPARATOR);
			messageBuilder.append("Kilka wierszy \n");
			logger.echoDev(messageBuilder.toString());

			Integer maxRowsCount = 1;
			while(allAppAccounts.next() && maxRowsCount < 4){
				transformResultSet = null;
				transformResultSet = adoDb.fetch(allAppAccounts, ResultSetTransformOutputEnum.FETCH_ROW);
				logger.echoDev(transformResultSet.toString());
				maxRowsCount++;
			}

			//zamknięcie i zwolnienie zasobów przechowywanych w ResultSet
			allAppAccounts.close();
			allAppAccounts = null;


			

			//formatowanie wszystkich wierszy do postaci Map
			allAppAccounts = adoDb.ExecSelect("SELECT * FROM appAccounts");
			transformResultSet = adoDb.fetch(allAppAccounts, ResultSetTransformOutputEnum.FETCH_ALL);


			//usunięcie danych tekstowych
			messageBuilder.delete(0, messageBuilder.length() - 1);

			//wypisanie danych
			messageBuilder.append(MESSAGES_SEPARATOR);
			messageBuilder.append("Wszystkie wiersze \n");
			messageBuilder.append(transformResultSet.toString());
			logger.echoDev(messageBuilder.toString());

			//usunięcie obiektu, gdyż nie będzie już wykorzystywany
			messageBuilder = null;

			//usunięcie danych z ResultSet
			allAppAccounts = null;

			//zamknięcię połączenia z bazą danych
			adoDb.disconnect();

			//zwolnienie zasobu
			adoDb = null;

			//jawne wywołanie garbage-collectora
			System.gc();

		}
		catch (DBQueryException ex) {
			logger.echoDev("","",ex);
		}
		catch (Exception ex) {
			logger.echoDev("","",ex);
		}
	}

}
